package com.learning.dynamic.executor.config;

import com.learning.dynamic.executor.executor.DynamicExecutor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Objects;

/**
 * @author Wang Xu
 * @date 2023/11/7
 */
public class DynamicExecutorImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
    private Environment env;

    @Override
    public void setEnvironment(Environment environment) {
        env = environment;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BindResult<DynamicProperties> bind = Binder.get(env).bind("dynamic.executor",
                Bindable.of(DynamicProperties.class));
        DynamicProperties dynamicProperties = bind.orElse(new DynamicProperties());
        if (Objects.nonNull(dynamicProperties.getDynamicExecutorPropertiesList())) {
            dynamicProperties.getDynamicExecutorPropertiesList().forEach(prop -> {
                RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
                rootBeanDefinition.setBeanClass(DynamicExecutor.class);
                rootBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(prop.getCorePoolSize());
                rootBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(prop.getMaximumPoolSize());
                rootBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(prop.getPoolName());
                registry.registerBeanDefinition(prop.getPoolName(), rootBeanDefinition);
            });
        }
    }
}